home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
ddjcompr
/
hstest
/
src
/
hstest.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-28
|
7KB
|
320 lines
//
// HSTEST.C
// this is a little demo & test programm for the kombination
// sliding directory & huffman compression
// the real kompression is done using a sliding directory mechanism pack(),
// which will eventually be farther compressed using a modified huffman
// method which takes some time as well, is currently not very efficient
// implemented, but may be used if space is really important,
// the first method should be chosen if the unpack time is of importance
// unpack(), written in assembler for speed reasons roughly decompresses
// some 25 KByte / Landmark or 1 MB on a 25 MHz 386 maschine
//
// warning : the code is not yet clean for byte ordering, it will work
// only on one type of maschine, the compressed files are probable not
// (yet) portable
//
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <tomlib.h>
#include "pack.h"
#define BUFFSIZE 0xf000
char far *inbuff = NULL;
char far * pbuff = NULL;
char far * hbuff = NULL;
char far *outbuff = NULL;
long p_hufflen = 0;
long p_huffsum = 0;
long p_nohuff = 0;
long p_huffind = 0;
long p_match,p_nmatch;
int fullprint = 0;
usage()
{
printf(
"HSTEST infile outfile [-options]\n"
" options are\n"
" -Uncompress infile to outfile, default is compress\n"
" -Full (and slow) compression, default is fast mode\n"
" -S print statistics\n"
" -Quiet mode\n"
" have Fun! tom ehlert\n");
exit(1);
}
int extract = FALSE;
int fullcompression = FALSE;
int statistics = FALSE;
int quiet = FALSE;
int fdin = 0
,fdout = 0;
//********************************************************************
// some support code
//********************************************************************
void qprintf(char *s)
{
if (!quiet)
printf(s);
}
main(int argc,char *argv[])
{
unsigned loop,anzblocks;
char *argptr;
while (argptr = getargs(&argc,argv,"/-"))
while (*++argptr)
switch(toupper(*argptr))
{
case 'U' : extract = TRUE; break;
case 'F' : fullcompression = TRUE; break;
case 'S' : statistics = TRUE; break;
case 'Q' : quiet = TRUE; break;
default : usage();
}
if (argc != 3)
{
usage();
}
if ((fdin = open(argv[1],O_RDONLY | O_BINARY)) < 0)
{
printf("can't read %s",argv[1]);
exit(1);
}
if ((fdout = open(argv[2],O_WRONLY | O_BINARY | O_CREAT | O_TRUNC,
S_IREAD|S_IWRITE)) < 0)
{
printf("can't write %s",argv[2]);
exit(1);
}
if ((inbuff = dosalloc((long)BUFFSIZE)) == NULL ||
( pbuff = dosalloc((long)BUFFSIZE)) == NULL ||
( hbuff = dosalloc((long)BUFFSIZE)) == NULL ||
(outbuff = dosalloc((long)BUFFSIZE)) == NULL )
{
printf("can't allocate enough memory for buffers");
exit(1);
}
tx_init(); // that supports my own custom profiler
// forget it
if (!quiet)
{
anzblocks = (unsigned)((filelength(fdin)+(BUFFSIZE-1))/BUFFSIZE);
for (loop = 0; loop < anzblocks; loop++)
printf("@");
for (loop = 0; loop < anzblocks; loop++)
printf("\b");
}
if (extract)
decompress();
else
compress();
}
// this is used for the statistic
long rd_time = 0;
long wr_time = 0;
long pack_time = 0;
long huff_time = 0;
long unpack_time = 0;
long insum = 0;
long psum = 0;
long hsum = 0;
long osum = 0;
# define NOT_COMPRESSED (('N'<<8)|'C')
# define HS_COMPRESSED (('H'<<8)|'S')
# define SL_COMPRESSED (('S'<<8)|'L')
do_write(unsigned mode,unsigned length,void far *buffer)
{
osum += length;
mikro_diff();
far_write(fdout,&mode,2);
far_write(fdout,&length,2);
far_write(fdout,buffer,length);
wr_time += mikro_diff();
qprintf("W");
}
compress()
{
unsigned rd,plen,hlen;
unsigned long ltime;
far_write(fdout,"te",2); // justy write my initials
// to begin of file
while (1)
{
mikro_diff(); // perform time analysis
// for each function
if ((rd = far_read(fdin,inbuff,BUFFSIZE)) == 0)
break;
rd_time += mikro_diff();
qprintf("R\b");
insum += rd;
mikro_diff();
plen = pack (pbuff,rd,inbuff,rd); // PACK
pack_time += mikro_diff();
if (fullprint)
printf("%5u packed packlen %5u --> time %5ld \n",rd,plen,ltime);
qprintf("P\b");
if (plen == 0xffff || plen >= rd)
{
psum += rd;
hsum += rd;
do_write(NOT_COMPRESSED,rd,inbuff);
continue;
}
psum += plen;
if (fullcompression)
{
mikro_diff();
hlen = hs_pack (hbuff,plen,pbuff,plen);
huff_time += mikro_diff();
qprintf("p\b");
if (hlen != 0xffff && hlen < plen)
{
hsum += hlen;
do_write(HS_COMPRESSED,hlen,hbuff);
continue;
}
}
hsum += plen;
do_write(SL_COMPRESSED,plen,pbuff);
}
if (statistics)
{
qprintf("\n");
printf("kompressed %ld Bytes down to %ld ",insum,osum);
if (fullcompression)
printf("(packsize %ld",psum);
printf("\n");
printf("times (in ms) : reading %ld writing %ld packing %ld",
rd_time/1000,wr_time/1000,pack_time/1000);
if(fullcompression)
printf(" huffing %ld",huff_time / 1000);
printf("\n");
}
}
decompress()
{
char b[2];
unsigned rd,mode,ulen,length;
read(fdin,b,2);
if (memcmp(b,"te",2))
quit("this is no known kompressed file,sorry\n");
while (1)
{
mikro_diff(); // perform time analysis
// for each function
if ((rd = far_read(fdin,&mode,2)) != 2)
{
if (rd == 0) // assume we are ready
break;
quit("error reading input file\n");
}
if ((rd = far_read(fdin,&length,2)) != 2)
quit("error reading input file\n");
if ((rd = far_read(fdin,inbuff,length)) != length)
quit("error reading input file\n");
rd_time += mikro_diff();
qprintf("R\b");
insum += rd;
mikro_diff();
switch(mode)
{
case NOT_COMPRESSED:
mikro_diff();
far_write(fdout,inbuff,length);
wr_time += mikro_diff();
qprintf("W");
osum += length;
break;
case HS_COMPRESSED:
mikro_diff();
ulen = hs_unpack(outbuff,inbuff,length);
unpack_time += mikro_diff();
qprintf("U\b");
far_write(fdout,outbuff,ulen);
wr_time += mikro_diff();
qprintf("W");
osum += ulen;
break;
case SL_COMPRESSED:
mikro_diff();
ulen = unpack(outbuff,inbuff,length);
unpack_time += mikro_diff();
qprintf("U\b");
far_write(fdout,outbuff,ulen);
wr_time += mikro_diff();
qprintf("W");
osum += ulen;
break;
}
}
if (statistics)
{
qprintf("\n");
printf("decompressed %ld Bytes to %ld\n",insum,osum);
printf("times (in ms) : reading %ld writing %ld unpacking %ld\n",
rd_time/1000,wr_time/1000,unpack_time/1000);
}
}